package dvx.mp.ivisual.desktop.ui;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.FileInputStream;

import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Node;

import org.apache.log4j.Logger;

public class VentanaPrincipal extends JFrame {
	/***/
	private static final long serialVersionUID = 1L;
	Logger log = Logger.getLogger(VentanaPrincipal.class);

	final private String TITLE_MENU = "Menú";
	final private String FILE_MENU_NAME = "src/main/resources/menu.xml";
	final private String XML_LABEL_ATTR_NAME = "label";
	final private String XML_CLASS_ATTR_NAME = "class-name";

	/***/
	private JSplitPane splitPane;
	private JTree treeMenu;
	private JDesktopPane desk;

	/**
	 * Create the frame.
	 */
	public VentanaPrincipal() {
		super("IVisualManager - DesktopApp");

		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setExtendedState(Frame.MAXIMIZED_BOTH);

		this.designUI();
		this.bindEvents();
	}

	private void designUI()	{
		splitPane = new JSplitPane();
		splitPane.setDividerLocation(200);// Relación del ancho del lado izquierdo
		getContentPane().add(splitPane, BorderLayout.CENTER);

		// LADO DERECHO
		desk = new JDesktopPane();
		splitPane.setRightComponent(desk);
		
		//LADO IZQUIERDO
		treeMenu = new JTree();
		Builder builder = new Builder();
		try {
			long timeStart = System.currentTimeMillis();

			Document doc = builder.build(
					new FileInputStream(FILE_MENU_NAME));

			Element rootXML = doc.getRootElement();
			DefaultMutableTreeNode rootMenu = new DefaultMutableTreeNode(TITLE_MENU);

			this.loadMenu(rootXML, rootMenu);

			DefaultTreeModel menuModel = (DefaultTreeModel) treeMenu.getModel();
			menuModel.setRoot(rootMenu);
			menuModel.reload();

			long timeEnd = System.currentTimeMillis();
			log.debug("Menú cargado en: " + (timeEnd - timeStart) + " ms");
		}catch(Exception e)	{
			e.printStackTrace();
		}

		JPanel pnlMenu = new JPanel();
		pnlMenu.setLayout(new GridLayout());
		pnlMenu.add(treeMenu);		

		JScrollPane scroll = new JScrollPane(pnlMenu);
		splitPane.setLeftComponent(scroll);
	}

	/**
	 * Lets to load the application menu from a XML object file representation
	 * @param xmlNode The node we want to iterate
	 * @param mnuNode The JTree node we want to populate
	 */
	private void loadMenu(Node xmlNode, DefaultMutableTreeNode mnuNode)	{
		for(int i = 0; i < xmlNode.getChildCount(); i++)	{
			Node child = xmlNode.getChild(i);

			if(Element.class.equals(child.getClass()))	{
				Element childElement = (Element) child;

				if("item".equals(childElement.getQualifiedName()))	{
					MenuItemObject mnuItem = new MenuItemObject(
							VentanaPrincipal.this.desk
							,childElement.getAttribute(XML_LABEL_ATTR_NAME).getValue()
							,childElement.getAttribute(XML_CLASS_ATTR_NAME).getValue());

					mnuNode.add(
							new DefaultMutableTreeNode(mnuItem));
				}

				if("category".equals(childElement.getQualifiedName()))	{
					DefaultMutableTreeNode categoria = new DefaultMutableTreeNode(
							childElement.getAttribute(XML_LABEL_ATTR_NAME).getValue());

					this.loadMenu(xmlNode.getChild(i), categoria);

					mnuNode.add(categoria);
				}
			}
		}
	}

	/**
	 * Bind objects to events
	 */
	private void bindEvents()	{
		this.treeMenu.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				/**
				 * Cuando un doble clic ocurre, se recupera el elemento del menú actualmente seleccionado
				 * y se utilizan los métodos del item para mostrar el JInternalFrame correspondiente
				 */
				if(2 == arg0.getClickCount())	{
					log.debug(VentanaPrincipal.this.treeMenu.getSelectionPath());
					// Path for the selected node
					TreePath selectedPath = VentanaPrincipal.this.treeMenu.getPathForLocation(
							arg0.getX(), arg0.getY());
					DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) selectedPath.getLastPathComponent();
					// If the selected TreeNode user object isn't a MenuItemObject
					Object obj = null;
					if(MenuItemObject.class != (obj = treeNode.getUserObject()).getClass())
					{ return; }
					// We use the MenuItemObject to instantiate a JInternalFrame and show it
					MenuItemObject selectedItemObject = (MenuItemObject) obj;
					log.debug(selectedItemObject);
					
					selectedItemObject.showActivity();
				}
			}
		});
	}
}